package org.alfresco.crowd;

import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.encoding.PasswordEncoder;

import org.alfresco.repo.security.authentication.AuthenticationComponentImpl;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.RepositoryAuthenticationDao;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.atlassian.crowd.integration.acegi.user.CrowdUserDetailsService;

public class CrowdAlfrescoAuthenticationComponent29 extends
		AuthenticationComponentImpl {

	private CrowdUserDetailsService userDetailsService;

	private AuthorityService authorityService;

	private RepositoryAuthenticationDao authenticationDao;

	private PasswordEncoder passwordEncoder;

	protected NodeService nodeService;

	protected PersonService personService;

	protected TransactionService transactionService;

	private static Log logger = LogFactory
			.getLog(CrowdAlfrescoAuthenticationComponent29.class);

	/*
	 * (non-Javadoc)
	 *
	 * @see org.alfresco.repo.security.authentication.AuthenticationComponentImpl#authenticateImpl(java.lang.String,
	 *      char[])
	 */
	@Override
	protected void authenticateImpl(String userName, char[] password)
			throws AuthenticationException {

		// This will implicitly call getUserDetails
		super.authenticateImpl(userName, password);

		AuthenticationHelper.authenticate(userName, password, logger,
				authenticationDao, userDetailsService, personService,
				nodeService, passwordEncoder);

	}

	/**
	 * Default implementation that makes an ACEGI object on the fly
	 *
	 * @param userName
	 * @return
	 */
	@Override
	public UserDetails getUserDetails(String userName) {

		return AuthenticationHelper.userDetails(userName, getPersonService(),
				getUserDetailsService(), logger);

	}

	/**
	 * Get the enum that describes NTLM integration
	 *
	 * @return NTLMMode
	 */
	public NTLMMode getNTLMMode() {
		return NTLMMode.PASS_THROUGH;
	}

	/**
	 * Get the password hash from the DAO
	 */
	public String getMD4HashedPassword(String userName) {
		logger.warn("Getting MD4 password. It may not be set correctly");
		return super.getMD4HashedPassword(userName);
	}

	/**
	 * IOC
	 *
	 * @param authenticationDao
	 */
	public void setAuthenticationDao(
			RepositoryAuthenticationDao authenticationDao) {
		this.authenticationDao = authenticationDao;
	}

	public void setUserDetailsService(CrowdUserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	public void setAuthorityService(AuthorityService authorityService) {
		this.authorityService = authorityService;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}

	public CrowdUserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

	public AuthorityService getAuthorityService() {
		return authorityService;
	}

	public void setNodeService(NodeService nodeService) {
		this.nodeService = nodeService;
	}

	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}

	public void setTransactionService(TransactionService transactionService) {
		this.transactionService = transactionService;
	}

	public NodeService getNodeService() {
		return nodeService;
	}

	public PersonService getPersonService() {
		return personService;
	}

	public TransactionService getTransactionService() {
		return transactionService;
	}

}
